home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Best of MacTutor - S…e Code for Volumes 1 to 5
/
The Best of MacTutor - Source Code for Volume 1-5 (Wayzata Technology)(6031)(1990).bin
/
Source Code
/
#13 (Oct 86)
/
c source
/
printw.c
< prev
next >
Wrap
C/C++ Source or Header
|
1986-09-09
|
12KB
|
518 lines
/* Sending text to window with
* function that accepts a variable
* number of parameters
*
* Compiled with LightspeedC
*
* Important note for Mac C users:
* Every place you see event->where,
* replace it with &event->where
*/
#include "abc.h"
#include "Quickdraw.h"
#include "EventMgr.h"
#include "WindowMgr.h"
#include "MenuMgr.h"
/* defines for menu ID's */
#define Mdesk 100
#define Mfile 101
#define Medit 102
#define Mwind 103
#define Mtest 104
/* Global variables */
MenuHandle menuDesk; /* menu handles */
MenuHandle menuFile;
MenuHandle menuEdit;
MenuHandle menuWind;
MenuHandle menuTest;
WindowPtr theWindow;
WindowRecord windowRec;
Rect dragbound;
Rect limitRect;
main()
{
initsys(); /* system initialization */
initapp(); /* application initialization */
eventloop();
}
/* system initialization
* note use of hard coded screen sizes
* with LightspeedC. This will work
* with other compilers but is not
* good practice
*/
initsys()
{
InitGraf(&thePort); /* these two lines done */
InitFonts(); /* automatically by Mac C */
InitWindows();
InitCursor();
InitMenus();
theWindow = Nil; /*indicates no window */
SetRect(&dragbound,0,0,512,250);
SetRect(&limitRect,60,40,508,244);
}
/*
* application initialization
* Sets up menus.
* Each menu is a separate group
* of lines. Note the last menu
* is appended but not inserted. This
* makes it part of the menu list but
* not in the menu bar.
*/
initapp()
{
menuDesk = NewMenu(Mdesk,CtoPstr("\24"));
AddResMenu (menuDesk, 'DRVR');
InsertMenu (menuDesk, 0);
menuFile = NewMenu(Mfile, CtoPstr("File"));
AppendMenu (menuFile,
CtoPstr("Open Window/M;Close Window/X;Quit/Q"));
AppendMenu (menuFile,
CtoPstr("(-;Show Test;(Hide Test"));
InsertMenu (menuFile, 0);
menuEdit = NewMenu(Medit, CtoPstr("Edit"));
AppendMenu (menuEdit,
CtoPstr("Undo;(-;Cut;Copy;Paste;Clear"));
InsertMenu (menuEdit, 0);
menuWind = NewMenu(Mwind, CtoPstr("Window"));
AppendMenu (menuWind,
CtoPstr("Hide;Show;New Title"));
InsertMenu (menuWind, 0);
menuTest = NewMenu(Mtest, CtoPstr("Test"));
AppendMenu (menuTest,
CtoPstr("Pick;One;Of;These"));
DrawMenuBar();
}
/* Event Loop
* Loop forever until Quit
*/
eventloop()
{
EventRecord theEvent;
char c;
short windowcode;
WindowPtr ww;
while(True)
{
if (theWindow) /* this code is here to prevent */
{ /* closing an already closed */
EnableItem(menuFile,2); /* window! */
DisableItem(menuFile,1);
}
else
{
EnableItem(menuFile,1);
DisableItem(menuFile,2);
}
if (GetNextEvent(everyEvent,&theEvent))
switch(theEvent.what)
{ /* only check key and */
case keyDown: /* mouse down events */
if (theEvent.modifiers & cmdKey)
{
c = theEvent.message & charCodeMask;
domenu(MenuKey(c));
}
break;
case mouseDown:
domouse(&theEvent);
break;
default:
break;
}
}
}
/* domouse
* handle mouse down events
*/
domouse(er)
EventRecord *er;
{
short windowcode;
WindowPtr whichWindow;
short ingo;
long size;
ushort t1 = 0xFFFF;
short t2 = 0xFFFF;
windowcode = FindWindow(er->where, &whichWindow);
switch (windowcode)
{
case inDesk:
if (theWindow notequal 0)
{
HiliteWindow(theWindow, False);
DrawGrowIcon(theWindow);
}
printw(" In Desk %d %ld %d ",10,123L,-456);
break;
case inMenuBar:
printw("\nIn MenuBar %u %d ",t2,t1);
domenu(MenuSelect(er->where));
break;
case inSysWindow:
SysBeep(1);
break;
case inContent:
printw("\nIn content %ld %d",700000,700000);
if (whichWindow equals theWindow)
{
HiliteWindow(whichWindow,True);
DrawGrowIcon(theWindow);
}
break;
case inDrag:
DragWindow(whichWindow, er->where, &dragbound);
DrawGrowIcon(theWindow);
break;
case inGrow:
/* not included this month */
break;
case inGoAway:
ingo = TrackGoAway(whichWindow,er->where);
if (ingo)
{
CloseWindow(whichWindow);
theWindow = Nil;
}
break;
}
}
/* domenu
* handles menu activity
* simply a dispatcher for each
* menu.
*/
domenu(mc)
long mc; /* menu result */
{
short menuId;
short menuitem;
menuId = HiWord(mc);
menuitem = LoWord(mc);
switch (menuId)
{
case Mdesk :
break; /* not handling DA's */
case Mfile :
dofile(menuitem);
break;
case Medit :
break;
case Mwind :
dowind(menuitem);
break;
case Mtest :
dotest(menuitem);
break;
}
HiliteMenu(0);
}
/* dofile
* handles file menu
*/
dofile(item)
short item;
{
char *title1; /* first title for window */
Rect boundsRect;
switch (item)
{
case 1 : /* open the window */
title1 = "ABC Window";
SetRect(&boundsRect,50,50,300,150);
theWindow = NewWindow(&windowRec, &boundsRect,
CtoPstr(title1),True,documentProc,
(WindowPtr) -1, True, 0);
DrawGrowIcon(theWindow);
PtoCstr(title1);
DisableItem(menuFile,1);
EnableItem(menuFile,2);
break;
case 2 : /* close the window */
CloseWindow(theWindow);
theWindow = Nil;
DisableItem(menuFile,2);
EnableItem(menuFile,1);
break;
case 3 : /* Quit */
ExitToShell();
break;
case 5 : /* Install additional menu */
InsertMenu(menuTest,0);
EnableItem(menuFile,6);
DisableItem(menuFile,5);
DrawMenuBar();
break;
case 6 : /* remove additional menu */
DeleteMenu(Mtest);
EnableItem(menuFile,5);
DisableItem(menuFile,6);
DrawMenuBar();
break;
}
}
/*
* dowind
* handles window menu
* Note that each case contains an
* if testing the existance of the
* window. This could be written
* with one if before the switch.
*/
dowind(item)
short item;
{
char *title2; /* second title for window */
switch (item)
{
case 1 : /* Hide */
if (theWindow)
HideWindow(theWindow);
break;
case 2 : /* Show */
if (theWindow)
ShowWindow(theWindow);
break;
case 3 : /* Change title */
if (theWindow)
{
title2 = "A Different Title";
SetWTitle(theWindow, CtoPstr(title2));
PtoCstr(title2);
}
break;
}
}
/* dotest
* Handles new menu.
* All this does is mark menu
* items if they are not marked and
* unmark them if they are.
*/
dotest(item)
short item;
{
short mark;
GetItemMark(menuTest,item,&mark);
if (mark)
CheckItem(menuTest,item,False);
else
CheckItem(menuTest,item,True);
}
/* Displays strings and numbers in a
* special window
* This function is designed to receive
* a variable number of parameters. The
* number is computed by the number of
* percent signs in the control string.
* If the number of parameters following the
* control string does not match the
* number of percent signs, expect
* the unexpected.
*/
printw(s)
char *s; /* the control string */
{
#define Bufsz 14 /* size of buffer to hold */
/* converted numbers */
static Rect boundsRect; /* variables for */
static Rect windowRect; /* defining printw */
static WindowRecord wrc; /* window, pw is */
static WindowPtr pw = 0; /* initialized to 0 */
WindowPtr oldport; /* save grafport here */
short linesz; /* size of line */
FontInfo info;
short nl;
Point pt;
RgnHandle updrgn; /* needed for scrolling */
char numAsStr[Bufsz]; /* number conversion */
short nsz; /* size of numbers (2 or 4) */
char **ts; /* ptr to ptr to ctrl string */
char *ps; /* ptr to parameters */
ulong num; /* for number conversion */
short convchar; /* found conversion char */
short islong; /* number is a long */
/* Window rectancgle coordinates */
#define wl 0
#define wr 512
#define wt 250
#define wb 342
GetPort(&oldport); /* save current graph port */
GetFontInfo(&info); /* compute line height */
linesz = info.ascent + info.descent;
if (pw equals 0) /* if window does not exist*/
{ /* open it */
SetRect(&boundsRect,wl,wt,wr,wb);
pw = NewWindow(&wrc, &boundsRect,
CtoPstr(""),True,plainDBox,
(WindowPtr) -1, True, 0);
nl = linesz; /* move down one line as */
} /* writing will be above */
else /* boundary. No need to */
nl = 0; /* move line if open */
SetPort(pw); /* Set port to this window */
Move(0,nl); /* Move (relative) */
ts = &s; /* get address of control string ptr */
ps = (char *)ts; /* convert to pointer to params */
ps += sizeof(long); /* skip over control string pointer*/
while (*s) /* loop until end of control string */
{
switch (*s) /* check each character */
{
case '%' : /* percent sign: check conversion */
s++; /* point to next char */
convchar = False; /* initialize conv loop */
islong = False;
do { /* until reach conv char */
switch (*s)
{
case 'l' : /* indicates a long */
islong = True;
s++;
break;
case 'u' : /* unsigned decimal */
case 'd' : /* signed decimal */
if (islong) /* extract number */
{
num = *(ulong*)ps;
nsz = sizeof(long);
}
else
{
num = *(ushort*)ps;
nsz = sizeof(short);
}
ps += nsz; /* point to next param */
/* convert number and write it to
* window
*/
ntoa(num,nsz,'u' - *s,numAsStr);
DrawString(CtoPstr(numAsStr));
convchar = True;
break;
/* strings, individual chars and hex * numbers not handled yet
*/
case 's' :
break;
case 'c' :
break;
/* if it is not any expected char,
* write it out and go on
*/
default :
DrawChar(*s);
convchar = True;
}
} while (not convchar);
break;
case '\n' : /* newline ('\n') in control string */
GetPen(&pt); /* find current pen position */
if (pt.v+linesz > wb-wt) /* if it goes off , */
{ /* scroll the window */
updrgn = NewRgn();
ScrollRect(&(pw->portRect),0,-linesz,updrgn);
DisposeRgn(updrgn); /* no update */
Move(0,-linesz); /* move onto window */
}
Move(-pt.h,linesz);/* move to next line */ break;
default : /* any other character gets */
DrawChar(*s); /* written on the window */
}
s++; /* move pointer to next char */
} /* in control string and cont*/
SetPort(oldport); /* restore orignal graf port */
}
/* Convert numbers to ascii strings
* Handles signed and unsigned
* short and long values
* Note: Length of string returned
* must be large enough to
* hold -2G (12 bytes)
*/
ntoa(n,len,issigned,s)
ulong n; /* number to convert */
short len; /* size of n (2 or 4)*/
short issigned; /* signed flag */
char *s; /* string to return */
{
char ts[12]; /* temporary string */
int i = 0; /* counter, initialized */
ulong m; /* working copy of */
long sm; /* to convert signed values */
if (n equals 0) /* if n is zero, place '0' */
ts[i++] = '0'; /* in temporary string */
else
{
if (issigned) /* if sign flag is set, */
{ /* convert to signed value */
if (len equals sizeof(long))
sm = (long)n;
else
sm = (short)n;
if (issigned = sm < 0) /* Check if value is */
n = -sm; /* negative. If so, */
} /* keep the flag and */
/* get the absolute value */
while (n) /* Convert number into ascii */
{ /* by repeatedly taking mod */
ts[i++] = n % 10 + '0'; /* and dividing. */
n /= 10; /* This gives a string in */
} /* reverse order */
if (issigned) /* If number was negative, */
ts[i++] = '-'; /* stick a minus sign in */
} /* the string.*/
do { /* Reverse the string */
*s++ = ts[--i]; /* to the correct direction*/
}
while (i);
*s = '\0'; /* Place null terminator on */
} /* string */